﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace GGetTestService.Services.Base
{
    public interface IBaseService<TEntity> where TEntity : class
    {
        /// <summary>
        /// 添加实体(单个)
        /// </summary>
        /// <param name="entity">实体对象</param>
        Task AddAsync(TEntity entity);

        /// <summary>
        /// 批量插入实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        Task AddRangeAsync(IList<TEntity> list);

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task UpdateAsync(TEntity entity);

        /// <summary>
        /// 批量更新实体
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        Task UpdateRangeAsync(IList<TEntity> list);

        /// <summary>
        /// 删除实体(单个)
        /// </summary>
        /// <param name="entity"></param>
        Task RemoveAsync(TEntity entity);

        /// <summary>
        /// 批量删除实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        Task RemoveRangeAsync(IList<TEntity> list);

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetAllListAsync();

        /// <summary>
        /// 获取所有数据(不跟踪实体状态)
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetAllListWithNoTrackingAsync();

        /// <summary>
        /// 根据queryable条件获取所有数据
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListAsync(IQueryable<TEntity> queryable);

        /// <summary>
        /// 根据queryable条件获取所有数据(不跟踪实体状态)
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(IQueryable<TEntity> queryable);

        /// <summary>
        /// 根据queryable条件获取分页数据(不跟踪实体状态)
        /// </summary>
        /// <param name="queryable"></param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(IQueryable<TEntity> queryable, int page, int pageSize);

        /// <summary>
        /// 根据expression条件获取所有数据
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 根据expression条件获取所有数据(不跟踪实体状态)
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 根据expression条件获取分页数据(不跟踪实体状态)
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> GetListWithNoTrackingAsync(Expression<Func<TEntity, bool>> expression, int page, int pageSize);

        /// <summary>
        /// 获取实体（主键）
        /// </summary>
        /// <param name="id">主键id</param>
        /// <returns></returns>
        Task<TEntity> GetModelByIdAsync(object id);

        /// <summary>
        /// 获取实体（条件）
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        Task<TEntity> GetModelAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 查询记录数
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns>记录数</returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returns>布尔值</returns>
        Task<bool> ExistAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 保存更改
        /// </summary>
        /// <returns></returns>
        Task<int> SaveChangesAsync();
    }
}